#region license
# This file is part of Grawlix.
# 
# Grawlix is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as
# published by the Free Software Foundation, either version 3 of
# the License, or (at your option) any later version.
# 
# Grawlix is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public
# License along with Grawlix.  If not, see
# <http://www.gnu.org/licenses/>.
#endregion

"""
Automatically seal methods in final classes and turn protected private
to allow for some leeway in implementing AST attributes.
"""

namespace Grawlix.Meta
import Boo.Lang.Compiler
import System

transient class SealMethodsInFinalClasses(
	Steps.AbstractVisitorCompilerStep):
"""Seal methods in final classes and make protected methods private."""
	
	public override def Run():
	"""Start the step."""
		Visit(CompileUnit);

	public static def OnMember(node as Ast.TypeMember):
	"""
	Seal members.
	Param node: The node to resolve.
	"""
		if node.DeclaringType.IsFinal:
			if node.NodeType != Ast.NodeType.Field:
				node.Modifiers |= Ast.TypeMemberModifiers.Final
			if node.IsProtected and not node.IsOverride:
				node.Modifiers &= ~Ast.TypeMemberModifiers.Protected
				node.Modifiers |= Ast.TypeMemberModifiers.Private
	
	public override def OnMethod(node as Ast.Method):
	"""
	Seal members.
	Param node: The node to resolve.
	"""
#		if node.Name == 'Finalize':
#		# Don't mess with finalizers
#			return
		OnMember(node)
	
	public override def OnProperty(node as Ast.Property):
	"""
	Seal members.
	Param node: The node to resolve.
	"""
		OnMember(node)
	
	public override def OnField(node as Ast.Field):
	"""
	Seal members.
	Param node: The node to resolve.
	"""
		OnMember(node)
	
	public override def OnCallableDefinition(node as Ast.CallableDefinition):
	"""
	Seal members.
	Param node: The node to resolve.
	"""
		OnMember(node)
	
	public override def OnEvent(node as Ast.Event):
	"""
	Seal members.
	Param node: The node to resolve.
	"""
		OnMember(node)
	
	public override def OnSpliceTypeMember(node as Ast.SpliceTypeMember):
	"""
	Seal members.
	Param node: The node to resolve.
	"""
		OnMember(node)
	

